/*
 * Copyright (C) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ACCESSIBILITY_SCREEN_READER_H
#define ACCESSIBILITY_SCREEN_READER_H


#include "accessibility_event_info.h"
#include "singleton.h"
#include "accessibility_gesture_event_handler.h"
#include "accessibility_accessibility_event_handler.h"
#include "key_event.h"
#include <map>

#define PERFORMANCE_TEST "PERFORMANCE_TEST "


namespace OHOS {
namespace Accessibility {

class ScreenReader {
    DECLARE_SINGLETON(ScreenReader)
public:

    bool OnStart();

    bool OnStop();
    /**
     * @Description: Handle the accessibility event, dispatch to sub-process.
     * @param uiEvent: accessibility event.
     */
    void OnAccessibilityEvent(const AccessibilityEventInfo &uiEvent);

    /* For common event */
    void OnCommonEvent(const int32_t eventType);

    /**
     * @Description: to log the element info of the element.
     * @param elementInfo: element info.
     */
    void HilogElementInfo(const AccessibilityElementInfo &elementInfo);

    /**
     * @Description: Get the parent element info of the element.
     * @param elementInfo: child element info.
     * @return: parent element info.
     */
    AccessibilityElementInfo FindParentElementInfo(const AccessibilityElementInfo &elementInfo);

    /**
     * @Description: Find first focusable parent of the element.
     * @param elementInfo: current element info.
     * @return: first focusable parent element info.
     */
    AccessibilityElementInfo FindFocusableParentElement(const AccessibilityElementInfo &elementInfo);

    /**
     * @Description: Execute simple action that just need one action.
     * @param action: action type.
     * @return: true if execute success, false if execute failed.
     */
    bool ExecuteAction(const ActionType action);
    
    /**
     * @Description: Insert cache history element id of the page by pageid and windowid.
     * @param windowId: window id.
     * @param pageId: page id.
     * @param elementId: element id.
     */
    void InsertCache(const int32_t windowId, const int32_t pageId, const int64_t elementId);

    /**
     * @Description: Get the cache history element id of the page by pageid and windowid.
     * @param windowId: window id.
     * @param pageId: page id.
     * @return: element id.
     */
    int64_t GetCacheElementId(const int32_t windowId, const int32_t pageId);

    bool FindRootElement(AccessibilityElementInfo &rootElementInfo);
    /**
     * @Description: Find the first element of the page by windowid.
     */
    bool FindFirstElement(AccessibilityElementInfo &firstElement);


    /**
     * @Description: Check if the element is focusable by clickable, componenttype and so on.
     * @param elementInfo: element info.
     */
    bool CheckFocusable(const AccessibilityElementInfo &elementInfo);

    /**
     * @Description: Draw the focus of the element.
     * @params elementInfo: element info to focus.
     * @param flag: focus flag. -1: first clickable child; 0: none; 1:last clickable child.
     */
    bool DrawFocus(const AccessibilityElementInfo &elementInfo, const int32_t flag = -1); // 默认原来是0，现改为-1

    /**
     * @Description: Get the content of the element in text child element.
     * @param elementInfo: element info.
     * @return: content of the element.
     */
    const std::string GetContent(const AccessibilityElementInfo &elementInfo);

    void SpeakFullScreen();

private:
    void SetKeyCodeToMmi(std::shared_ptr<MMI::KeyEvent>& keyEvent, const bool isPress, const int32_t keyCode);
    bool TransmitActionToMmi(const int32_t action);

    bool isScreenReaderEnabled_ =false;
    AccessibilityEventHandler accessibilityEventHandler_;
    GestureEventHandler gestureEventHandler_;
    std::map<int64_t, int64_t> pageFocusedElementCache_; // < windowId<<32+pageId, elementId >
};

} // namespace Accessibility
} // namespace OHOS

#endif // ACCESSIBILITY_SCREEN_READER_H